package com.woniuxy.controller;

import com.woniuxy.entity.Appinfo;
import com.woniuxy.entity.Appointment;
import com.woniuxy.entity.Car;
import com.woniuxy.service.AppointmentService;
import com.woniuxy.service.CampService;
import com.woniuxy.service.CarService;
import com.woniuxy.service.UserService;
import com.woniuxy.util.Result;
import com.woniuxy.vo.AppinfoVO;
import com.woniuxy.vo.AppointmentVO;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
import java.text.SimpleDateFormat;
import java.util.*;


@RestController
@CrossOrigin
public class AppointmentController {
    @Resource
    private AppointmentService appointmentService;
    @Resource
    private CarService carService;
    @Resource
    private CampService campService;
    @Resource
    private UserService userService;
    @RequestMapping("/order/appointment")
    public Result selectCampOrderByStatus(Integer status,Integer userId) throws Exception{
        Map<String,Object> map = new HashMap<String,Object>();
        map.put("userId",userId);
        map.put("status",status);
        return new Result("200","success",null,appointmentService.selectCampOrderByStatus(map));
    }
//    房车预约，判断所选时间段内房车是否空闲
    @RequestMapping("/order/checkAppointmentTime")
    public Result checkAppointmentTime(Integer carId,String startTime,String endTime) throws Exception{
        List<Appointment> apps = appointmentService.selectAppointmentBycarIdAndStatus(carId);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        long begin = sdf.parse(startTime).getTime();
        long end = sdf.parse(endTime).getTime();
        boolean flag = true;
        for(int i=0;i<apps.size();i++){
            long start = apps.get(i).getStartTime().getTime();
            long over = apps.get(i).getEndTime().getTime();
            if((begin<=start)&&(end>start)){
                flag=false;
            }
            if((begin>start)&&(begin<=over)){
                flag=false;
            }
        }
        return new Result("200",""+flag,null,null);
    }
//    支付成功,生成订单,接收参数为集合 待支付1，已支付2,使用中3，已完成4
    @RequestMapping("/order/addAppointment/success")
    public Result addAppointment1(@RequestBody List<AppinfoVO> appinfoVO) throws Exception{
        //成功状态为已支付
        addAppointmentComment(appinfoVO,2);

        return new Result("200","success",null,null);
    }
//    支付失败  状态为待支付
    @RequestMapping("/order/addAppointment/fail")
    public Result addAppointment2(@RequestBody List<AppinfoVO> appinfoVO) throws Exception{
        //支付失败状态为未支付
        addAppointmentComment(appinfoVO,1);
        return new Result("200","success",null,null);
    }
//    扫码开门
    /*
     * 二维码携带carId，从session中获取当前的userId 查询数据库，检测当前用户是否预约过，且时间是否吻合，状态是否为已支付
     */
    @RequestMapping("/order/openDoor")
    public Result openDoor(Integer carId,Integer userId) throws Exception{
        System.out.println("userId========="+userId);
        if (userId==null && userId==0){
            return new Result("200","未登录",null,null);
        }
        List<Appointment> list = appointmentService.selectAppointmentByCarId(carId, 2, userId);
        for(int i=list.size()-1;i>=0;i--){
            if (list.get(i).getStatus()==1 || list.get(i).getStatus()==4){
                list.remove(i);
            }
        }
        Date date = new Date();
        long time = date.getTime();
        //判断解锁日期是否合法
        for (Appointment appointment : list) {
            long begin = appointment.getStartTime().getTime();
            long end = appointment.getEndTime().getTime();
            if(begin<time && time<end){
                //订单状态设置为使用中
                appointment.setStatus(3);
                appointmentService.updateAppointment(appointment);
                return new Result("200","开门",null,null);
            }
        }
        return new Result("200","不开",null,null);
    }

    /**
     * 取消订单处理
     * 预约时间未到取消预约  退还全部租金和一半押金 待支付1，已支付2,使用中3，已完成4
     * @param appId
     * @return
     * @throws Exception
     */

    @RequestMapping("/order/cancelAppointmentBefor")
    public Result cancelAppointmentBefor(Integer appId) throws Exception{
        Appointment app = appointmentService.selectAppointmentByAppId(appId);
        app.setStatus(4);
        //这里判断一下当前时间是否超出了预约时间，如果超时未入住则不能按提前取消预约处理
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date date = new Date();
        Map<String, Object> map = new HashMap<>();
        map.put("userId",app.getUserId());
        if(date.getTime()>app.getEndTime().getTime()){
            //已经超出了离店时间  改变订单状态为已完成且不能执行取消预约
            updateCarStatus(app.getCarId(),0);
            appointmentService.updateAppointment(app);
            //退款至用户余额
            map.put("account",-app.getDeposit());
            userService.updateUserAccount(map);
            return new Result("200","已逾期，退还押金"+app.getDeposit()+"元",null,null);
        }
        if (date.getTime()>app.getStartTime().getTime()){
            //在入住期间 按天数计费
            int time = (int) (date.getTime() - app.getStartTime().getTime())/(1000*60*60*24)+1;
            double price = app.getTotal()/Integer.valueOf(app.getDays());
            //总消费
            double countTotal = time*price;
            //退还
            double backMoney = app.getTotal()-countTotal+app.getDeposit();

            map.put("account",-backMoney);
            userService.updateUserAccount(map);

            updateCarStatus(app.getCarId(),0);
            app.setDays(time+"");
            app.setEndTime(date);
            app.setTotal(countTotal);
            appointmentService.updateAppointment(app);
            return new Result("200","入住"+time+"天，共消费"+countTotal+"元，退还:"+backMoney+"元",null,null);
        }
        //预约时间未到退房 退还全款+一半押金
        double backMoney = app.getTotal()+app.getDeposit()/2;
        map.put("account",-backMoney);
        userService.updateUserAccount(map);

        app.setWait("已取消");
        updateCarStatus(app.getCarId(),0);
        appointmentService.updateAppointment(app);
        return new Result("200","已取消预约，租金将会在两小时内退还给原账户",null,null);
    }
    //提一个公共方法
    public void addAppointmentComment(List<AppinfoVO> appinfoVO,Integer status) throws Exception{
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Appinfo appinfo = new Appinfo();
        appinfo.setIdcard(appinfoVO.get(0).getIdNum());
        appinfo.setName(appinfoVO.get(0).getName());
        appinfo.setTel(appinfoVO.get(0).getTel());
        int appInfoId = appointmentService.insertAppinfoReturnKey(appinfo);
        for (int i=0;i<appinfoVO.size();i++){
            Appointment app = new Appointment();
            //判断是否存在appId，有则执行更新，没有则执行新增
            if(appinfoVO.get(i).getAppId()!=null){
                app.setAppointmentId(appinfoVO.get(i).getAppId());
                app.setStatus(status);
                appointmentService.updateAppointment(app);
                return;
            }
            app.setCarId(carService.selectCarId(appinfoVO.get(i).getCarName()));
            app.setCampId(campService.selectCampIdByCampName(appinfoVO.get(i).getCampName()));
            app.setStartTime(sdf.parse(appinfoVO.get(i).getStartTime()));
            app.setEndTime(sdf.parse(appinfoVO.get(i).getEndTime()));
            app.setDays(appinfoVO.get(i).getDays()+"");
            //userId从Session或主体对像中获取
            app.setUserId(appinfoVO.get(i).getUserId());
            app.setTotal(appinfoVO.get(i).getDays()*appinfoVO.get(i).getPrice());
            app.setDeposit(200.0);
            //已支付
            app.setStatus(status);
            app.setAppinfoId(appinfo.getAppinfoId());
            appointmentService.insertAppointment(app);
            if (status!=1){
                //说明预约成功了
                updateCarStatus(app.getCarId(),1);
            }
        }
    }
    //支付成功订单生成后需要改变房车的状态  0空闲  1已预约  2已入住  3维修  4退休
    public int updateCarStatus(Integer carId,Integer status) throws Exception{
        Car car = new Car();
        car.setCarId(carId);
        car.setStatus(status);
        return carService.updateCarStatus(car);
    }

}
